; Virginia Tech * ECE 2504 * Fall 2007
; Kevin Green	2007
; #905-131-654
;
; 
;Program description:
;
;First, the program calls ROW parity function, which calculates row parity
;by looping through array entries and checking each bit. It toggles a parity
;value on or off at each 1 it encounters.
;
;Next, column parity checks parity by XORing all the array values together
;then inverting the result and storing it in the last register.

; Define CPU registers, etc. with include file
	
	title "ECE 2504 Project #3"
	#include <P16F84.inc>


; Define data memory locations
; ** DEFINE SCRATCH OR TEMPORARY DATA MEMORY LOCATIONS HERE. **
; ** USE LOCATIONS 0x0C-0x1F.       **

;More locations
parity	equ	0x0C		;parity storage
i		equ 0x0D		;looping counter
n		equ 0x0F		;looping counter
m		equ 0x10		;looping counter



w	equ	0	; DDR = 0 - store the result in w
f	equ	1	;store in f

;bit locations
paritybit	equ 7;which bit we set to save parity info
ignorebit1	equ 5;first bit to ignore
ignorebit2	equ 6;second bit location to ignore


; Definitions of data array memory locations. for debuggin
size	equ	0x20		; location of number of bytes in array
start	equ	0x21		; first byte in the array / first row
second	equ 0x22
third	equ 0x23
fourth	equ 0x24
fifth	equ	0x25		
sixth	equ 0x26		




; Program
	org	0	; start program at program memory location 0
	goto begin	; jump to the first instruction


	org	0x10    ; specifies the address of the first instruction
begin
;******************************************
;     PUT  YOUR MAIN PROGRAM HERE.        *
;******************************************

	call ROW
	call COLUMN

; ** PUT YOUR LAST INSTRUCTION OF THE MAIN ROUTINE HERE TO SIMPLIFY TRACING. **

last	goto	last  		; done (endless loop)



;****************************************************
;	Place the ROW subroutine here
;
;----------------------------------------------------
; ROW subroutine:  
;
; This subroutine computes the row parity of a register m, in which register W 
; passes the register address m. 
;
;
ROW		movlw	start		;move start to W
		movwf	FSR			;set FSR to W for start of loop	
		
		;reset loop counter to 1st row
		movf	size,w;
		movwf	i			;set the loop counter
		decf	i			;only do first n-1 values
		clrf parity			;clear parity


loop
		btfsc INDF,0		;check LSB in start
			comf	parity	;skip if ^ is 0
		btfsc INDF,1		;check 1 in FSR
			comf	parity	;skip if ^ is 0
		btfsc INDF,2		;check 2 in FSR
			comf	parity	;skip if ^ is 0
		btfsc INDF,3		;check 3 in FSR
			comf	parity	;skip if ^ is 0
		btfsc INDF,4		;check 4 in FSR
			comf	parity	;skip if ^ is f0
		btfsc INDF,5		;check 4 in FSR
			comf	parity	;skip if ^ is f0
		btfsc INDF,6		;check 4 in FSR
			comf	parity	;skip if ^ is f0		


		btfss parity,0		;check first bit of parity
			bsf INDF,paritybit		;set parity bit to 1 if parity is 0


		incf FSR			;point to next part of array	
		clrf parity;		;reset parity toggle
		decfsz i			;decrement counter
			goto loop		;repeat if i>0

	return			; done, return from subroutine ROW
;------------------------------------------------------



;****************************************************
;	Place the COLUMN subroutine here
;
;----------------------------------------------------
; COLUMN subroutine:  
;
; This subroutine computes the COLUMN parity of the nth bit, in which register W 
; passes the value n. 
;
;
COLUMN 	movfw	size	;move size of array
		movwf	i		;set loop counter
		decf	i			;only do first n-1 values
		movlw	start	;address of start to W
		movwf	FSR		;save start address (from w) to FSR
		clrw			;reset w to 0

colloop	xorwf 	INDF,w	;XOR w with current register (first is start)
		incf	FSR		;increment FSR
		decfsz	i		;decrement i
			goto colloop;repeat loop until i=0
		
		movwf INDF		; complement w
		comf  INDF		;woot
	return			; done, return from subroutine COLUMN
;------------------------------------------------------



end			; end of source file
